#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QSerialPortInfo>
#include "QTimer"
#include "QDebug"
#include "qmessagebox.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
    , modbusHandler(new ModbusHandler(this))
{
    ui->setupUi(this);
    refreshTimer = new QTimer(this);
    indicatorTimer = new QTimer(this); // 初始化指示灯闪烁定时器
    ui->connectButton->setText("打开端口");
    ui->statusLabel->setText("端口未打开");
    ui->baudRateBox->addItems({"9600", "19200", "38400", "57600", "115200"});
    ui->baudRateBox->setCurrentIndex(5);  // 默认115200
    autoReadActive = false;
    modbusHandler->loadEnergyData();  // 启动时加载电量数据
    ui->tableWidget->setRowCount(28);
    ui->tableWidget->setColumnCount(4);
    ui->tableWidget->setHorizontalHeaderLabels({"名称", "数值", "名称", "数值"});
    ui->label_communicationIndicator->setStyleSheet("background-color: gray; border-radius: 10px;");
    connect(ui->readButton, &QPushButton::clicked, this, &MainWindow::onAutoReadButtonClicked);
    connect(ui->baudRateBox, SIGNAL(currentIndexChanged(int)), this, SLOT(onBaudRateSelected(int)));
    connect(modbusHandler, &ModbusHandler::dataRead, this, &MainWindow::updateData);
    connect(refreshTimer, &QTimer::timeout, this, [=]() {modbusHandler->readAllRegisters(); }); // 新增方法，一次性读取全部寄存器
    connect(modbusHandler, &ModbusHandler::energyUpdated,this, &MainWindow::updateEnergyDisplay);
    connect(modbusHandler, &ModbusHandler::dataCollected,this, &MainWindow::recordData);
    connect(refreshTimer, &QTimer::timeout, this, &MainWindow::updateIndicator);
    indicatorTimer->start(500); // 每500ms触发一次
}

MainWindow::~MainWindow()
{
     modbusHandler->saveEnergyData();  // 关闭时保存电量数据
    delete ui;
}

void MainWindow::on_connectButton_clicked()
{
    // QString portName = ui->comboBox_Port->currentText();
    // modbusHandler->connectToPort(portName);

    if (portOpen) {
        modbusHandler->disconnectPort();
        portOpen = false;
        ui->connectButton->setText("打开端口");
        ui->statusLabel->setText("端口已关闭");
        ui->label_communicationIndicator->setStyleSheet("background-color: gray; border-radius: 10px;");
    } else {
        QString portName = ui->comboBox_Port->currentText();
        modbusHandler->connectToPort(portName);

        if (modbusHandler->isPortOpen()) {
            portOpen = true;
            ui->connectButton->setText("关闭端口");
            ui->statusLabel->setText("端口已打开");

        } else {
            ui->statusLabel->setText("端口打开失败");
        }
    }

}

void MainWindow::onAutoReadButtonClicked()
{
    //modbusHandler->readAllRegisters();
    if(modbusHandler->isPortOpen())
    {
        if (autoReadActive)
        {
            refreshTimer->stop();
            ui->readButton->setText("开始读取");
            autoReadActive = false;
        }
        else
        {
            refreshTimer->start(100);  // 100ms刷新
            ui->readButton->setText("暂停读取");
            autoReadActive = true;
        }
    }
    else
    {
    QMessageBox::warning(this, "错误", "请先打开串口");

    }

}

void MainWindow::updateData(double voltage, double current, int soc, int soh,
                             double temperatures[6], double cellVoltages[16],
                             quint16 protectionFlags1, quint16 protectionFlags2,
                             double ratedCapacity,int cellCount,int cycleCount)
{

    // 标记有数据接收
        isDataReceived = true;

    // 启动一个定时器，1秒后将 isDataReceived 重置为 false
    QTimer::singleShot(1000, this, [this]() {isDataReceived = false;});

    QVector<QPair<QString, QString>> data = {
        {"标称容量", QString("%1 Ah").arg(ratedCapacity)},
        {"电池串数", QString("%1").arg(cellCount)},
        {"总电压", QString("%1 V").arg(voltage)},
        {"总电流", QString("%1 A").arg(current)},
        {"SOC", QString("%1 %").arg(soc)},
        {"SOH", QString("%1 %").arg(soh)},
        {"循环次数", QString("%1 次").arg(cycleCount)}
    };

    // 保护标志解析
    QString protectionStatus_1 = "正常",protectionStatus_2 = "正常";
    if (protectionFlags1 || protectionFlags2) {
        protectionStatus_1 = "";
        protectionStatus_2 = "";
         if (protectionFlags1 & (1 << 0)) protectionStatus_1 += "UVT 硬件欠压";
         if (protectionFlags1 & (1 << 1)) protectionStatus_1 += "OVT 硬件过压";
         if (protectionFlags1 & (1 << 2)) protectionStatus_1 += "PUV 总压欠压";
         if (protectionFlags1 & (1 << 3)) protectionStatus_1 += "POV 总压过压";
         if (protectionFlags1 & (1 << 4)) protectionStatus_1 += "SCD 短路保护";
         if (protectionFlags1 & (1 << 5)) protectionStatus_1 += "OCD2_DSG 三级放电过流";
         if (protectionFlags1 & (1 << 6)) protectionStatus_1 += "OCD_T 硬件放电过流";
         if (protectionFlags1 & (1 << 7)) protectionStatus_1 += "OV_T 硬件过压";
         if (protectionFlags1 & (1 << 8)) protectionStatus_1 += "OT_DSG 电池放电过温";
         if (protectionFlags1 & (1 << 9)) protectionStatus_1 += "OC_DSG 放电过流";
         if (protectionFlags1 & (1 << 10)) protectionStatus_1 += "UT_DSG 低温放电";
         if (protectionFlags1 & (1 << 11)) protectionStatus_1 += "UT_CHG 低温充电";
         if (protectionFlags1 & (1 << 12)) protectionStatus_1 += "OT_MOS MOS过温";
         if (protectionFlags1 & (1 << 13)) protectionStatus_1 += "OC_CHG 充电过流";
         if (protectionFlags1 & (1 << 14)) protectionStatus_1 += "OV 过压";
         if (protectionFlags1 & (1 << 15)) protectionStatus_1 += "UV 欠压";
         if (protectionFlags2 & (1 << 8)) protectionStatus_2 += "TEMP_E 温度采样异常";
         if (protectionFlags2 & (1 << 10)) protectionStatus_2 += "CHG 充电MOS打开";
         if (protectionFlags2 & (1 << 11)) protectionStatus_2 += "DSG 放电MOS打开";

    }


    data.append({"保护标志1", protectionStatus_1});
    data.append({"保护标志2",protectionStatus_2});

    for (int i = 0; i < 6; ++i) {
        data.append({QString("温度%1").arg(i+1), QString("%1 ℃").arg(temperatures[i])});
    }

    for (int i = 0; i < 16; ++i) {
        data.append({QString("单体电压%1").arg(i+1), QString("%1 mV").arg(cellVoltages[i])});
    }

    int rowCount = (data.size() + 1) / 2;
    ui->tableWidget->setRowCount(rowCount);
    ui->tableWidget->setColumnCount(4);
    ui->tableWidget->setHorizontalHeaderLabels({"名称", "数值", "名称", "数值"});

    for (int i = 0; i < data.size(); ++i) {
        int row = i / 2;
        int col = (i % 2) * 2;
        ui->tableWidget->setItem(row, col, new QTableWidgetItem(data[i].first));
        ui->tableWidget->setItem(row, col+1, new QTableWidgetItem(data[i].second));
    }

    // 保护标志高亮闪烁
    static bool flash = false;


    for (int i = 0; i < data.size(); ++i) {
        if (data[i].first.contains("保护标志") && data[i].second != "正常") {


        }
        else
        {
            // flash = !flash;
            // QColor color = flash ? QColor(Qt::red) : QColor(Qt::yellow);
            // int row = i / 2;
            // int col = (i % 2) * 2;
            // ui->tableWidget->item(row, col)->setBackground(color);
            // ui->tableWidget->item(row, col+1)->setBackground(color);
        }
    }
    ui->tableWidget->resizeColumnsToContents();
}

void MainWindow::on_pushButton_ScanningCOM_clicked()
{
    // 列出所有串口
    ui->comboBox_Port->clear();

    foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts()) {
        ui->comboBox_Port->addItem(info.portName());
    }
}

void MainWindow::onBaudRateSelected(int index)
{
    static const int rates[] = {9600, 19200, 38400, 57600, 115200};
    int selectedBaudRate = rates[index];
    modbusHandler->setBaudRate(selectedBaudRate);
}


void MainWindow::updateEnergyDisplay(double chargeAh, double dischargeAh)
{
    ui->label_ChargeAh->setText(QString("充电量: %1 Ah").arg(chargeAh, 0, 'f', 2));
    ui->label_DischargeAh->setText(QString("放电量: %1 Ah").arg(dischargeAh, 0, 'f', 2));
    chargeAh_save=chargeAh;
    dischargeAh_save=dischargeAh;
}

void MainWindow::on_pushButton_clear_clicked()
{
    modbusHandler->clearEnergy();  // 清零ModbusHandler中的电量数据
    ui->label_ChargeAh->setText("充电量: 0.00 Ah");
    ui->label_DischargeAh->setText("放电量: 0.00 Ah");
    modbusHandler->saveEnergyData();  // 清零后立即保存
}

void MainWindow::on_recordButton_clicked()
{
    if (isRecording) {
        // 停止记录
        isRecording = false;
        ui->recordButton->setText("开始记录");

        if (recordFile.isOpen()) {
            recordFile.close();
            qDebug() << "✅ 数据记录已停止，文件已保存。";
        }
    } else {
        // 开始记录
        QString fileName = QCoreApplication::applicationDirPath() + "/data_log_" +
                           QDateTime::currentDateTime().toString("yyyyMMdd_HHmmss") + ".csv";
        recordFile.setFileName(fileName);

        if (recordFile.open(QIODevice::WriteOnly | QIODevice::Text)) {
            recordStream.setDevice(&recordFile);
            //recordStream.setCodec("UTF-8");
            // 添加 UTF-8 BOM (防止 Excel 打开时中文乱码)
            //recordFile.write("\xEF\xBB\xBF");
            QString str_titlebar;

            str_titlebar="时间戳,总电压(V),总电流(A),SOC(%),SOH(%),充电量(Ah),放电量(Ah),温度1,温度2,温度3,温度4,温度5,温度6,1单体电压,2单体电压"
                           ",3单体电压,4单体电压,5单体电压,6单体电压,7单体电压,8单体电压,9单体电压,10单体电压,11单体电压,12单体电压,13单体电压"
                           ",14单体电压,15单体电压,16单体电压,保护标志1,保护标志2,电池串数,标称容量,循环次数,\n";
            //recordStream.setCodec("GB2312");
            // recordStream << "时间戳,总电压(V),总电流(A),SOC(%),SOH(%),充电量(Ah),放电量(Ah),温度1,,温度2,温度3,温度4,温度5,温度6,1单体电压,2单体电压"
            //                 ",2单体电压,3单体电压,4单体电压,5单体电压,6单体电压,7单体电压,8单体电压,9单体电压,10单体电压,11单体电压,12单体电压,13单体电压"
            //                 ",14单体电压,15单体电压,16单体电压,保护标志1,保护标志2,电池串数,标称容量,循环次数,\n";  // CSV表头

            recordStream<<str_titlebar.toUtf8();

            isRecording = true;
            ui->recordButton->setText("停止记录");

            qDebug() << "✅ 数据记录已开始：" << fileName;
        } else {
            QMessageBox::warning(this, "错误", "无法创建数据记录文件！");
        }
    }
}
void MainWindow::recordData(const QString &timestamp,double voltage, double current, int soc, int soh,
                            double temperatures[6], double cellVoltages[16],
                            quint16 protectionFlags1, quint16 protectionFlags2,
                            double ratedCapacity,int cellCount,int cycleCount)
{
    if (isRecording && recordFile.isOpen()) {
        recordStream << timestamp << ","
                     << voltage << ","
                     << current << ","
                     << soc << ","
                     << soh << ","
                     << chargeAh_save << ","
                     << dischargeAh_save << ","
                     << temperatures[0] << ","
                     << temperatures[1] << ","
                     << temperatures[2] << ","
                     << temperatures[3] << ","
                     << temperatures[4] << ","
                     << temperatures[5] << ","
                     << cellVoltages[0] << ","
                     << cellVoltages[1] << ","
                     << cellVoltages[2] << ","
                     << cellVoltages[3] << ","
                     << cellVoltages[4] << ","
                     << cellVoltages[5] << ","
                     << cellVoltages[6] << ","
                     << cellVoltages[7] << ","
                     << cellVoltages[8] << ","
                     << cellVoltages[9] << ","
                     << cellVoltages[10] << ","
                     << cellVoltages[11] << ","
                     << cellVoltages[12] << ","
                     << cellVoltages[13] << ","
                     << cellVoltages[14] << ","
                     << cellVoltages[15] << ","
                     << protectionFlags1 << ","
                     << protectionFlags2 << ","
                     << cellCount << ","
                     << ratedCapacity << ","
                     << cycleCount <<"\n";

        qDebug() << "protectionFlags1,protectionFlags2" <<protectionFlags1<< "/"<<protectionFlags2;
        qDebug() << "cellCount,ratedCapacity,cycleCount" << cellCount<< "/"<< ratedCapacity<< "/"<< cycleCount;

        recordStream.flush();  // 实时写入文件，避免数据丢失
    }
}
void MainWindow::updateIndicator()
{
    if (modbusHandler->isPortOpen())
    {
    if (isDataReceived) {
        // 如果有数据接收，指示灯闪烁
        static bool isGreen = false;
        isGreen = !isGreen;
        if (isGreen) {
            ui->label_communicationIndicator->setStyleSheet("background-color: green; border-radius: 10px;");
        } else {
            ui->label_communicationIndicator->setStyleSheet("background-color: gray; border-radius: 10px;");
        }
    } else {
        // 如果没有数据接收，指示灯保持绿色
        ui->label_communicationIndicator->setStyleSheet("background-color: green; border-radius: 10px;");
    }
    }
    else {
        ui->label_communicationIndicator->setStyleSheet("background-color: gray; border-radius: 10px;");
    }


}

